#include "Reader.h"
#include <iostream>
#include <sstream>
#include <string>
#include <fstream>

using namespace std;

Reader::Reader(void)
{
}

Reader::~Reader(void)
{
}

// Load markers (feature points) in to vector
vector<int> Reader::loadMarkers(const char * fileName) 
{
	ifstream infile;
	infile.open(fileName);

	vector<int> markers;

	// Read markers until the end of file
	while(!infile.eof())     
	{
		int m1 = -1;
		int m2 = -1;
		infile >> m1 >> m2;
		markers.push_back(m1);
		markers.push_back(m2);
	}
	infile.close();

	return markers;
}

// Read the obj file and return in a mesh representation
TriangleMesh Reader::loadObjFile( const char* fileName )
{
   ifstream fileStream( fileName, ifstream::in );
   // Maximum line lenght in obj file
   char objLine[256];

   // Vertex coordinates v = (v1, v2, v3)
   float v1 = NULL,v2= NULL,v3= NULL;
   char str;

   // Triangle face vertex indexes
   int i1,i2,i3;

   TriangleMesh mesh;

   while( !fileStream.eof() )
   {
      fileStream.getline( objLine, 255 );
      stringstream ss;
      ss << objLine;
      if( objLine[0] == 'v' )
      {
         ss >> str >> v1 >> v2 >> v3;
		 mesh.addVertex(v1, v2, v3);
      }
      else if( objLine[0] == 'f' )
      {
         ss >> str >> i1 >> i2 >> i3;                 
		 mesh.addFace(i1, i2, i3);
      }
   }

   return mesh;
}

// Write triangle mesh into obj file
void Reader::saveObjFile(const char * fileName, TriangleMesh mesh)
{
	ofstream savefile;
	savefile.open (fileName);
 
		int numVert = mesh.getNumVert();
		int numFace = mesh.getNumFace();
		// Write vertices
		for(int i = 1; i <= numVert; i++)
		{
			float emptyV[3] = {0.0f, 0.0f, 0.0f};
			float * v = mesh.getVertex(i, emptyV);
			savefile << "v " << v[0] << " " << v[1] << " " << v[2] << endl;
		}
		// Write faces
		for(int i = 1; i <= numFace; i++)
		{
			int emptyF[3] = {0, 0, 0};
			int* f = mesh.getFace(i, emptyF);
			savefile << "f " << f[0] << " " << f[1] << " " << f[2] << endl;
		}

		savefile.close();
}

void Reader::saveObjFile(const char * fileName, float *geom, int nV, int *tri, int nT)
{
	ofstream savefile;
	savefile.open (fileName);
 
		int numVert = nV;
		int numFace = nT;
		// Write vertices
		for(int i = 0; i < numVert; i++)
		{
			float v[3] = { geom[i*3], geom[i*3 + 1], geom[i*3 + 2] };
			savefile << "v " << v[0] << " " << v[1] << " " << v[2] << endl;
		}
		// Write faces
		for(int i = 0; i < numFace; i++)
		{
			int f[3] = {tri[i*3], tri[i*3 + 1], tri[i*3 + 2]};
			savefile << "f " << f[0] << " " << f[1] << " " << f[2] << endl;
		}

		savefile.close();
}

void Reader::saveRuntimeInfo(const char *fileName, int num_verts, int num_triangles, double runningTime, int iterations) {
	ofstream savefile;
	savefile.open(fileName);
	savefile.precision(4);
	savefile << "Number of vertices: " << num_verts << endl;
	savefile << "Number of triangles: " << num_triangles << endl;
	savefile << "Running time: " << runningTime << "s" << " (" << runningTime / 60.0 << " min)" <<endl;
	savefile << "Iterations: " << iterations << endl;
	savefile.close();
}